<html>
<head><meta charset="utf-8"><title>why-ptr-read · t-compiler/wg-nll · Zulip Chat Archive</title></head>
<h2>Stream: <a href="https://rust-lang.github.io/zulip_archive/stream/122657-t-compiler/wg-nll/index.html">t-compiler/wg-nll</a></h2>
<h3>Topic: <a href="https://rust-lang.github.io/zulip_archive/stream/122657-t-compiler/wg-nll/topic/why-ptr-read.html">why-ptr-read</a></h3>

<hr>

<base href="https://rust-lang.zulipchat.com">

<head><link href="https://rust-lang.github.io/zulip_archive/style.css" rel="stylesheet"></head>

<a name="130227344"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122657-t-compiler/wg-nll/topic/why-ptr-read/near/130227344" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> nikomatsakis <a href="https://rust-lang.github.io/zulip_archive/stream/122657-t-compiler/wg-nll/topic/why-ptr-read.html#130227344">(Jul 24 2018 at 18:18)</a>:</h4>
<p>so <span class="user-mention" data-user-id="116266">@Santiago Pastorino</span> was asking me about what <span class="user-mention" data-user-id="116083">@pnkfelix</span> meant by this:</p>
<blockquote>
<p>I'm looking at it now as well, since I didn't see any notes from @Santiago Pastorino . The main interesting complication so far is that DiagnosticBuilderimplements Drop, so you have to use ptr::read to pull out its self.diagnostic (and then mem::forget(self) afterward).</p>
</blockquote>
<p>and I thought I might as well answer it here. This is in reference to the <code>DiagnosticBuilder</code> thread...</p>



<a name="130227353"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122657-t-compiler/wg-nll/topic/why-ptr-read/near/130227353" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> nikomatsakis <a href="https://rust-lang.github.io/zulip_archive/stream/122657-t-compiler/wg-nll/topic/why-ptr-read.html#130227353">(Jul 24 2018 at 18:18)</a>:</h4>
<p>... the situation is that you cannot move out of a field from a type that implements <code>Drop</code></p>



<a name="130227363"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122657-t-compiler/wg-nll/topic/why-ptr-read/near/130227363" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> nikomatsakis <a href="https://rust-lang.github.io/zulip_archive/stream/122657-t-compiler/wg-nll/topic/why-ptr-read.html#130227363">(Jul 24 2018 at 18:18)</a>:</h4>
<p>e.g., if <code>Foo</code> implements <code>Drop</code>, then you cannot do <code>let x = foo.a</code></p>



<a name="130227374"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122657-t-compiler/wg-nll/topic/why-ptr-read/near/130227374" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> nikomatsakis <a href="https://rust-lang.github.io/zulip_archive/stream/122657-t-compiler/wg-nll/topic/why-ptr-read.html#130227374">(Jul 24 2018 at 18:18)</a>:</h4>
<p>the reason for this is that -- when the <code>Drop</code> for <code>foo</code> should run -- it would have an "incomplete" value</p>



<a name="130227387"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122657-t-compiler/wg-nll/topic/why-ptr-read/near/130227387" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> nikomatsakis <a href="https://rust-lang.github.io/zulip_archive/stream/122657-t-compiler/wg-nll/topic/why-ptr-read.html#130227387">(Jul 24 2018 at 18:19)</a>:</h4>
<p>and it was felt it would be too confusing to e.g. have the <code>Drop</code> not run if you have moved out from the value (too easy to screw up)</p>



<a name="130227400"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122657-t-compiler/wg-nll/topic/why-ptr-read/near/130227400" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> nikomatsakis <a href="https://rust-lang.github.io/zulip_archive/stream/122657-t-compiler/wg-nll/topic/why-ptr-read.html#130227400">(Jul 24 2018 at 18:19)</a>:</h4>
<p>so in this case there was a <code>struct DiagnosticBuilder { handler, diagnostic }</code> and we wanted to put the <code>diagnostic</code> field into a vector</p>



<a name="130227412"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122657-t-compiler/wg-nll/topic/why-ptr-read/near/130227412" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> nikomatsakis <a href="https://rust-lang.github.io/zulip_archive/stream/122657-t-compiler/wg-nll/topic/why-ptr-read.html#130227412">(Jul 24 2018 at 18:19)</a>:</h4>
<p>we can't just move it because <code>DiagnosticBuilder</code> implements <code>Drop</code> -- it does so that it can panic if you fail to emit</p>



<a name="130227426"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122657-t-compiler/wg-nll/topic/why-ptr-read/near/130227426" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> nikomatsakis <a href="https://rust-lang.github.io/zulip_archive/stream/122657-t-compiler/wg-nll/topic/why-ptr-read.html#130227426">(Jul 24 2018 at 18:19)</a>:</h4>
<p>I had suggested the simplest fix, which was to do <code>vec.push(self.diagnostic.clone())</code>, but that is somewhat inefficient</p>



<a name="130227430"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122657-t-compiler/wg-nll/topic/why-ptr-read/near/130227430" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> nikomatsakis <a href="https://rust-lang.github.io/zulip_archive/stream/122657-t-compiler/wg-nll/topic/why-ptr-read.html#130227430">(Jul 24 2018 at 18:20)</a>:</h4>
<p>in that it does a clone</p>



<a name="130227489"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122657-t-compiler/wg-nll/topic/why-ptr-read/near/130227489" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> nikomatsakis <a href="https://rust-lang.github.io/zulip_archive/stream/122657-t-compiler/wg-nll/topic/why-ptr-read.html#130227489">(Jul 24 2018 at 18:20)</a>:</h4>
<p><span class="user-mention" data-user-id="116083">@pnkfelix</span> opted instead to use <code>ptr::read</code>, which is an unsafe function that copies a value <em>without</em> moving it -- kind of cheats and duplicates a value that is not supposed to be duplicated</p>



<a name="130227506"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122657-t-compiler/wg-nll/topic/why-ptr-read/near/130227506" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> nikomatsakis <a href="https://rust-lang.github.io/zulip_archive/stream/122657-t-compiler/wg-nll/topic/why-ptr-read.html#130227506">(Jul 24 2018 at 18:20)</a>:</h4>
<p>he then used <code>mem::forget</code> to cause the original value to be ignored and to never run its destructor</p>



<a name="130227514"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122657-t-compiler/wg-nll/topic/why-ptr-read/near/130227514" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> nikomatsakis <a href="https://rust-lang.github.io/zulip_archive/stream/122657-t-compiler/wg-nll/topic/why-ptr-read.html#130227514">(Jul 24 2018 at 18:20)</a>:</h4>
<p>this is mildly more efficient but obviously more error prone</p>



<a name="130227549"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122657-t-compiler/wg-nll/topic/why-ptr-read/near/130227549" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> pnkfelix <a href="https://rust-lang.github.io/zulip_archive/stream/122657-t-compiler/wg-nll/topic/why-ptr-read.html#130227549">(Jul 24 2018 at 18:21)</a>:</h4>
<p>I also decided the “cost” of an unsafe block (In terms of future programmer revIew effort) was justified here</p>



<a name="130227573"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122657-t-compiler/wg-nll/topic/why-ptr-read/near/130227573" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> pnkfelix <a href="https://rust-lang.github.io/zulip_archive/stream/122657-t-compiler/wg-nll/topic/why-ptr-read.html#130227573">(Jul 24 2018 at 18:21)</a>:</h4>
<p>In that if I did a clone, that <em>also</em> would impose future effort for people to review and understand what was going on</p>



<a name="130227638"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122657-t-compiler/wg-nll/topic/why-ptr-read/near/130227638" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> pnkfelix <a href="https://rust-lang.github.io/zulip_archive/stream/122657-t-compiler/wg-nll/topic/why-ptr-read.html#130227638">(Jul 24 2018 at 18:22)</a>:</h4>
<p>Namely that it’s not really duplicating state; it wants to be a move but we can’t express that via safe code</p>



<a name="130227673"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122657-t-compiler/wg-nll/topic/why-ptr-read/near/130227673" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> pnkfelix <a href="https://rust-lang.github.io/zulip_archive/stream/122657-t-compiler/wg-nll/topic/why-ptr-read.html#130227673">(Jul 24 2018 at 18:23)</a>:</h4>
<p>And so I just decided that ptr::read + mem::forget directly expresses intent</p>



<a name="130227694"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122657-t-compiler/wg-nll/topic/why-ptr-read/near/130227694" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> pnkfelix <a href="https://rust-lang.github.io/zulip_archive/stream/122657-t-compiler/wg-nll/topic/why-ptr-read.html#130227694">(Jul 24 2018 at 18:24)</a>:</h4>
<p>That is: I really was doing this for readability, not efficiency</p>



<a name="130227744"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122657-t-compiler/wg-nll/topic/why-ptr-read/near/130227744" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> pnkfelix <a href="https://rust-lang.github.io/zulip_archive/stream/122657-t-compiler/wg-nll/topic/why-ptr-read.html#130227744">(Jul 24 2018 at 18:24)</a>:</h4>
<p>But it’s possible my model of readability is busted</p>



<a name="130227752"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122657-t-compiler/wg-nll/topic/why-ptr-read/near/130227752" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> nikomatsakis <a href="https://rust-lang.github.io/zulip_archive/stream/122657-t-compiler/wg-nll/topic/why-ptr-read.html#130227752">(Jul 24 2018 at 18:24)</a>:</h4>
<p>heh :)</p>



<a name="130227808"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122657-t-compiler/wg-nll/topic/why-ptr-read/near/130227808" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> nikomatsakis <a href="https://rust-lang.github.io/zulip_archive/stream/122657-t-compiler/wg-nll/topic/why-ptr-read.html#130227808">(Jul 24 2018 at 18:25)</a>:</h4>
<blockquote>
<p>Namely that it’s not really duplicating state; it wants to be a move but we can’t express that via safe code</p>
</blockquote>
<p>I wonder ... it would be kind of neat to move some operation for this. meh.</p>



<a name="130228007"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122657-t-compiler/wg-nll/topic/why-ptr-read/near/130228007" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> simulacrum <a href="https://rust-lang.github.io/zulip_archive/stream/122657-t-compiler/wg-nll/topic/why-ptr-read.html#130228007">(Jul 24 2018 at 18:29)</a>:</h4>
<p>If the fields are public in theory can't you pattern match safely?</p>



<a name="130228276"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122657-t-compiler/wg-nll/topic/why-ptr-read/near/130228276" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> nikomatsakis <a href="https://rust-lang.github.io/zulip_archive/stream/122657-t-compiler/wg-nll/topic/why-ptr-read.html#130228276">(Jul 24 2018 at 18:33)</a>:</h4>
<p>I think I'd prefer for there to be an explicit operation to "disable" the dtor</p>



<a name="130228280"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122657-t-compiler/wg-nll/topic/why-ptr-read/near/130228280" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> nikomatsakis <a href="https://rust-lang.github.io/zulip_archive/stream/122657-t-compiler/wg-nll/topic/why-ptr-read.html#130228280">(Jul 24 2018 at 18:33)</a>:</h4>
<p>in any case "pattern matching" is not visible in MIR land</p>



<a name="130228283"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122657-t-compiler/wg-nll/topic/why-ptr-read/near/130228283" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> nikomatsakis <a href="https://rust-lang.github.io/zulip_archive/stream/122657-t-compiler/wg-nll/topic/why-ptr-read.html#130228283">(Jul 24 2018 at 18:33)</a>:</h4>
<p>so I'd prefer for that not to be the rule :)</p>



<a name="130228344"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122657-t-compiler/wg-nll/topic/why-ptr-read/near/130228344" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> nikomatsakis <a href="https://rust-lang.github.io/zulip_archive/stream/122657-t-compiler/wg-nll/topic/why-ptr-read.html#130228344">(Jul 24 2018 at 18:34)</a>:</h4>
<p>in most cases, I suspect (as in this one...) you really only  want to grab a single field</p>



<a name="130228417"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122657-t-compiler/wg-nll/topic/why-ptr-read/near/130228417" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> simulacrum <a href="https://rust-lang.github.io/zulip_archive/stream/122657-t-compiler/wg-nll/topic/why-ptr-read.html#130228417">(Jul 24 2018 at 18:35)</a>:</h4>
<p><code>let Foo { field, ... } = my_var;</code> though, right?</p>



<a name="130228480"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122657-t-compiler/wg-nll/topic/why-ptr-read/near/130228480" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> simulacrum <a href="https://rust-lang.github.io/zulip_archive/stream/122657-t-compiler/wg-nll/topic/why-ptr-read.html#130228480">(Jul 24 2018 at 18:36)</a>:</h4>
<p>I agree it's not every explicit though</p>



<a name="130231256"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122657-t-compiler/wg-nll/topic/why-ptr-read/near/130231256" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Santiago Pastorino <a href="https://rust-lang.github.io/zulip_archive/stream/122657-t-compiler/wg-nll/topic/why-ptr-read.html#130231256">(Jul 24 2018 at 19:22)</a>:</h4>
<p><span class="user-mention" data-user-id="116009">@nikomatsakis</span> thanks for the clarification</p>



<a name="130231445"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122657-t-compiler/wg-nll/topic/why-ptr-read/near/130231445" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> pnkfelix <a href="https://rust-lang.github.io/zulip_archive/stream/122657-t-compiler/wg-nll/topic/why-ptr-read.html#130231445">(Jul 24 2018 at 19:26)</a>:</h4>
<blockquote>
<p>I think I'd prefer for there to be an explicit operation to "disable" the dtor</p>
</blockquote>
<p>(there have been proposals for ways to do this; usually to simultaneously disable the dtor and move all the fields, or move into an "interior view" of the whole struct)</p>



<a name="130234335"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122657-t-compiler/wg-nll/topic/why-ptr-read/near/130234335" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jake Goulding <a href="https://rust-lang.github.io/zulip_archive/stream/122657-t-compiler/wg-nll/topic/why-ptr-read.html#130234335">(Jul 24 2018 at 20:17)</a>:</h4>
<p>I've created these functions before, decomposing a type into a tuple of it's parts</p>



<a name="130234346"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122657-t-compiler/wg-nll/topic/why-ptr-read/near/130234346" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jake Goulding <a href="https://rust-lang.github.io/zulip_archive/stream/122657-t-compiler/wg-nll/topic/why-ptr-read.html#130234346">(Jul 24 2018 at 20:17)</a>:</h4>
<p>I noticed hyper did something similar <a href="https://docs.rs/hyper/0.12.7/hyper/struct.Request.html#method.into_parts" target="_blank" title="https://docs.rs/hyper/0.12.7/hyper/struct.Request.html#method.into_parts">https://docs.rs/hyper/0.12.7/hyper/struct.Request.html#method.into_parts</a></p>



<a name="130234525"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122657-t-compiler/wg-nll/topic/why-ptr-read/near/130234525" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> simulacrum <a href="https://rust-lang.github.io/zulip_archive/stream/122657-t-compiler/wg-nll/topic/why-ptr-read.html#130234525">(Jul 24 2018 at 20:20)</a>:</h4>
<p>With the proposal to special-case <code>ManuallyDrop</code> we could potentially make it special in that you can move out of fields from it too</p>



<a name="130234541"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122657-t-compiler/wg-nll/topic/why-ptr-read/near/130234541" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> simulacrum <a href="https://rust-lang.github.io/zulip_archive/stream/122657-t-compiler/wg-nll/topic/why-ptr-read.html#130234541">(Jul 24 2018 at 20:21)</a>:</h4>
<p>So you'd do something like `let field = ManuallyDrop::new(bar).field;</p>



<hr><p>Last updated: Aug 07 2021 at 22:04 UTC</p>
</html>